import { ref, watch, onMounted, onUnmounted } from 'vue'
import { compress, decompress } from 'lz-string'

interface DraftData<T = any> {
  version: string
  expireAt: number
  data: T
}

const DRAFT_VERSION = '1.0'
const EXPIRE_DAYS = 2
const AUTO_SAVE_INTERVAL = 30000 // 30秒
const DEBOUNCE_DELAY = 2000 // 2秒防抖

/**
 * 深度克隆数据，确保压缩不会影响原始数据格式
 */
function deepClone<T>(data: T): T {
  return JSON.parse(JSON.stringify(data))
}

/**
 * 压缩数据
 */
function compressData<T>(data: T): string {
  try {
    // 深度克隆，确保不改变原始数据
    const clonedData = deepClone(data)
    const draftData: DraftData<T> = {
      version: DRAFT_VERSION,
      expireAt: Date.now() + EXPIRE_DAYS * 24 * 60 * 60 * 1000,
      data: clonedData
    }
    const jsonString = JSON.stringify(draftData)
    return compress(jsonString)
  } catch (error) {
    console.error('压缩数据失败:', error)
    throw error
  }
}

/**
 * 解压缩数据
 */
function decompressData<T>(compressed: string): T | null {
  try {
    const jsonString = decompress(compressed)
    if (!jsonString) {
      console.warn('解压缩失败: 数据为空')
      return null
    }

    const draftData: DraftData<T> = JSON.parse(jsonString)

    // 验证数据结构
    if (!draftData || typeof draftData !== 'object') {
      console.warn('解压缩失败: 数据结构无效')
      return null
    }

    if (draftData.version !== DRAFT_VERSION) {
      console.warn('解压缩失败: 版本不匹配')
      return null
    }

    // 检查是否过期
    if (draftData.expireAt < Date.now()) {
      console.info('草稿已过期，自动清除')
      return null
    }

    return draftData.data
  } catch (error) {
    console.error('解压缩数据失败:', error)
    return null
  }
}

/**
 * 清理所有过期的草稿
 */
function cleanExpiredDrafts(): void {
  try {
    const keysToRemove: string[] = []

    // 遍历所有 localStorage 键
    for (let i = 0; i < localStorage.length; i++) {
      const key = localStorage.key(i)
      if (!key || !key.startsWith('draft-')) {
        continue
      }

      const compressed = localStorage.getItem(key)
      if (!compressed) {
        continue
      }

      try {
        const jsonString = decompress(compressed)
        if (!jsonString) {
          keysToRemove.push(key)
          continue
        }

        const draftData = JSON.parse(jsonString)
        if (!draftData || !draftData.expireAt) {
          keysToRemove.push(key)
          continue
        }

        // 检查是否过期
        if (draftData.expireAt < Date.now()) {
          keysToRemove.push(key)
        }
      } catch (error) {
        // 解析失败，标记删除
        keysToRemove.push(key)
      }
    }

    // 删除过期或无效的草稿
    keysToRemove.forEach(key => {
      localStorage.removeItem(key)
      console.info(`已清理草稿: ${key}`)
    })
  } catch (error) {
    console.error('清理过期草稿失败:', error)
  }
}

/**
 * 自动保存 Composable
 * @param key 存储键名，格式: draft-{module}-{name}
 * @param data 要保存的响应式数据
 * @param options 配置选项
 */
export function useAutoSave<T extends object>(
  key: string,
  data: { value: T },
  options: {
    enabled?: boolean // 是否启用自动保存
    autoRecover?: boolean // 是否自动恢复草稿（默认true）
    onRecover?: (recoveredData: T) => void // 恢复回调（可选，用于特殊处理）
  } = {}
) {
  const { enabled = true, autoRecover = true, onRecover } = options

  let saveTimer: number | null = null
  let debounceTimer: number | null = null
  const isSaving = ref(false)

  /**
   * 保存草稿（静默）
   */
  const saveDraft = () => {
    if (!enabled || !data.value) {
      return
    }

    try {
      const compressed = compressData(data.value)
      localStorage.setItem(key, compressed)
      console.debug(`草稿已保存: ${key}`)
    } catch (error) {
      console.error('保存草稿失败:', error)
    }
  }

  /**
   * 带防抖的保存
   */
  const debouncedSave = () => {
    if (debounceTimer) {
      clearTimeout(debounceTimer)
    }
    debounceTimer = window.setTimeout(() => {
      saveDraft()
    }, DEBOUNCE_DELAY)
  }

  /**
   * 恢复草稿（静默）
   */
  const recoverDraft = (): T | null => {
    try {
      const compressed = localStorage.getItem(key)
      if (!compressed) {
        return null
      }

      const recoveredData = decompressData<T>(compressed)
      if (!recoveredData) {
        // 数据无效或过期，删除
        localStorage.removeItem(key)
        return null
      }

      console.debug(`草稿已恢复: ${key}`)
      return recoveredData
    } catch (error) {
      console.error('恢复草稿失败:', error)
      return null
    }
  }

  /**
   * 清除草稿
   */
  const clearDraft = () => {
    try {
      localStorage.removeItem(key)
      console.debug(`草稿已清除: ${key}`)
    } catch (error) {
      console.error('清除草稿失败:', error)
    }
  }

  /**
   * 初始化
   */
  onMounted(() => {
    // 清理所有过期草稿
    cleanExpiredDrafts()

    // 静默恢复草稿（仅当 autoRecover 为 true 时）
    if (enabled && autoRecover) {
      const recoveredData = recoverDraft()
      if (recoveredData) {
        // 如果提供了恢复回调，使用回调处理
        if (onRecover) {
          onRecover(recoveredData)
        } else {
          // 否则直接赋值
          Object.assign(data.value, recoveredData)
        }
      }
    }

    if (enabled) {

      // 监听数据变化，触发防抖保存
      watch(
        data,
        () => {
          debouncedSave()
        },
        { deep: true }
      )

      // 定时自动保存
      saveTimer = window.setInterval(() => {
        saveDraft()
      }, AUTO_SAVE_INTERVAL)
    }
  })

  /**
   * 清理
   */
  onUnmounted(() => {
    if (saveTimer) {
      clearInterval(saveTimer)
      saveTimer = null
    }
    if (debounceTimer) {
      clearTimeout(debounceTimer)
      debounceTimer = null
    }
  })

  return {
    saveDraft,
    clearDraft,
    recoverDraft,
    isSaving
  }
}
